QuickOPC User's Guide and Reference
Use multiple-operation methods instead of looping
Best Practices > Use multiple-operation methods instead of looping
In This Topic

Overview

Due to way OPC internally works, it is significantly more efficient to perform more operations at once. Whenever your application logic allows it, use methods with the word Multiple in their name, i.e. methods that work on multiple elements (such as OPC items) at once, and try to group together a bigger number of operations. This approach gives much better performance.

This rule, while already very important, becomes super-critical with OPC XML-DA subscriptions, because OPC XML-DA does not have any way to modify existing subscriptions (add or remove items to/from the subscriptions). Every modification to a subscription forces QuickOPC to discard an existing subscription with all its items, and create a new one with a modified set of items. If you properly call the SubscribeMultipleItems method for this, at least this operation is done just once. But if you loop and attempt to do SubscribeItem with OPC XML-DA repeatedly, each such call will cause the OPC subscription be destroyed and re-created, which is extremely inefficient.

Example - OPC Data Access

.NET

// This example shows how to read values of 4 items at once, and display them.

using System;
using System.Diagnostics;
using OpcLabs.BaseLib.OperationModel;
using OpcLabs.EasyOpc.DataAccess;

namespace DocExamples.DataAccess._EasyDAClient
{
    class ReadMultipleItemValues
    {
        public static void Main1()
        {
            // Instantiate the client object.
            var client = new EasyDAClient();

            ValueResult[] valueResults = client.ReadMultipleItemValues("OPCLabs.KitServer.2",
                new DAItemDescriptor[]
                {
                    "Simulation.Random", "Trends.Ramp (1 min)", "Trends.Sine (1 min)", "Simulation.Register_I4"
                });

            for (int i = 0; i < valueResults.Length; i++)
            {
                ValueResult valueResult = valueResults[i];
                Debug.Assert(!(valueResult is null));

                if (valueResult.Succeeded)
                    Console.WriteLine($"valueResults({i}).Value: {valueResult.Value}");
                else
                    Console.WriteLine($"valueResults({i}) *** Failure: {valueResult.ErrorMessageBrief}");
            }
        }


        // Example output:
        //
        //valueResults(0).Value: 0.00125125888851588
        //valueResults(1).Value: 0.732510924339294
        //valueResults(2).Value: -0.993968485238202
        //valueResults(3).Value: 0
    }
}
# This example shows how to read values of 4 items at once, and display them.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc

# Import .NET namespaces.
from OpcLabs.EasyOpc import *
from OpcLabs.EasyOpc.DataAccess import *
from OpcLabs.EasyOpc.DataAccess.OperationModel import *
from OpcLabs.EasyOpc.OperationModel import *


# Instantiate the client object.
client = EasyDAClient()

#
valueResultArray = IEasyDAClientExtension.ReadMultipleItemValues(client, [
    DAReadItemArguments(ServerDescriptor('OPCLabs.KitServer.2'), DAItemDescriptor('Simulation.Random')),
    DAReadItemArguments(ServerDescriptor('OPCLabs.KitServer.2'), DAItemDescriptor('Trends.Ramp (1 min)')),
    DAReadItemArguments(ServerDescriptor('OPCLabs.KitServer.2'), DAItemDescriptor('Trends.Sine (1 min)')),
    DAReadItemArguments(ServerDescriptor('OPCLabs.KitServer.2'), DAItemDescriptor('Simulation.Register_I4')),
    ])

for i, valueResult in enumerate(valueResultArray):
    assert valueResult is not None
    if valueResult.Succeeded:
        print('valueResultArray[', i, '].Value: ', valueResult.Value, sep='')
    else:
        print('valueResultArray[', i, '] *** Failure: ', valueResult.ErrorMessageBrief, sep='')
# This example shows how to read values of 4 items at once, and display them.

#requires -Version 5.1
using namespace OpcLabs.EasyOpc.DataAccess

# The path below assumes that the current directory is [ProductDir]/Examples-NET/PowerShell/Windows .
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcClassicCore.dll"
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcClassic.dll"
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcClassicComponents.dll"

# Instantiate the client object.
$client = New-Object EasyDAClient

$valueResults = [IEasyDAClientExtension]::ReadMultipleItemValues($client, 
    "OPCLabs.KitServer.2", @(
        (New-Object DAItemDescriptor("Simulation.Random")),
        (New-Object DAItemDescriptor("Trends.Ramp (1 min)")),
        (New-Object DAItemDescriptor("Trends.Sine (1 min)")),
        (New-Object DAItemDescriptor("Simulation.Register_I4"))
        ))

for ($i = 0; $i -lt $valueResults.Length; $i++) {
    $valueResult = $valueResults[$i]
    if ($valueResult.Succeeded) {
        Write-Host "valueResults($($i)).Value: $($valueResult.Value)"
    }
    else {
        Write-Host "valueResults($($i)) *** Failure: $($valueResult.ErrorMessageBrief)"
    }
}


# Example output:
#
#valueResults(0).Value: 0.00125125888851588
#valueResults(1).Value: 0.732510924339294
#valueResults(2).Value: -0.993968485238202
#valueResults(3).Value: 0

COM

// This example shows how to read values of 4 items at once, and display them.

class procedure ReadMultipleItemValues.Main;
var
  Arguments: OleVariant;
  Client: OpcLabs_EasyOpcClassic_TLB._EasyDAClient;
  I: Cardinal;
  ReadItemArguments1: _DAReadItemArguments;
  ReadItemArguments2: _DAReadItemArguments;
  ReadItemArguments3: _DAReadItemArguments;
  ReadItemArguments4: _DAReadItemArguments;
  ValueResult: _ValueResult;
  Results: OleVariant;
begin
  ReadItemArguments1 := CoDAReadItemArguments.Create;
  ReadItemArguments1.ServerDescriptor.ServerClass := 'OPCLabs.KitServer.2';
  ReadItemArguments1.ItemDescriptor.ItemID := 'Simulation.Random';

  ReadItemArguments2 := CoDAReadItemArguments.Create;
  ReadItemArguments2.ServerDescriptor.ServerClass := 'OPCLabs.KitServer.2';
  ReadItemArguments2.ItemDescriptor.ItemID := 'Trends.Ramp (1 min)';

  ReadItemArguments3 := CoDAReadItemArguments.Create;
  ReadItemArguments3.ServerDescriptor.ServerClass := 'OPCLabs.KitServer.2';
  ReadItemArguments3.ItemDescriptor.ItemID := 'Trends.Sine (1 min)';

  ReadItemArguments4 := CoDAReadItemArguments.Create;
  ReadItemArguments4.ServerDescriptor.ServerClass := 'OPCLabs.KitServer.2';
  ReadItemArguments4.ItemDescriptor.ItemID := 'Simulation.Register_I4';

  Arguments := VarArrayCreate([0, 3], varVariant);
  Arguments[0] := ReadItemArguments1;
  Arguments[1] := ReadItemArguments2;
  Arguments[2] := ReadItemArguments3;
  Arguments[3] := ReadItemArguments4;

  // Instantiate the client object
  Client := CoEasyDAClient.Create;

  TVarData(Results).VType := varArray or varVariant;
  TVarData(Results).VArray := PVarArray(
    Client.ReadMultipleItemValues(Arguments));

  // Display results
  for I := VarArrayLowBound(Results, 1) to VarArrayHighBound(Results, 1) do
  begin
      ValueResult := IInterface(Results[I]) as _ValueResult;

      if ValueResult.Succeeded then
        WriteLn('results(', i, ').Value: ', ValueResult.Value)
      else
        WriteLn('results(', i, ') *** Failure: ', ValueResult.ErrorMessageBrief);
  end;

  VarClear(Results);
  VarClear(Arguments);
end;
// This example shows how to read the values of 4 different items at once.

mle_outputtext.Text = ""

// Instantiate the client object
OLEObject client
client = CREATE OLEObject
client.ConnectToNewObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")

// Prepare arguments.

OLEObject readItemArguments1
readItemArguments1 = CREATE OLEObject
readItemArguments1.ConnectToNewObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
readItemArguments1.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
readItemArguments1.ItemDescriptor.ItemID = "Simulation.Random"

OLEObject readItemArguments2
readItemArguments2 = CREATE OLEObject
readItemArguments2.ConnectToNewObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
readItemArguments2.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
readItemArguments2.ItemDescriptor.ItemID = "Trends.Ramp (1 min)"

OLEObject readItemArguments3
readItemArguments3 = CREATE OLEObject
readItemArguments3.ConnectToNewObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
readItemArguments3.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
readItemArguments3.ItemDescriptor.ItemID = "Trends.Sine (1 min)"

OLEObject readItemArguments4
readItemArguments4 = CREATE OLEObject
readItemArguments4.ConnectToNewObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
readItemArguments4.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
readItemArguments4.ItemDescriptor.ItemID = "Simulation.Register_I4"

OLEObject readItemArgumentsList
readItemArgumentsList = CREATE OLEObject
readItemArgumentsList.ConnectToNewObject("OpcLabs.BaseLib.Collections.ElasticVector")
readItemArgumentsList.Add(readItemArguments1)
readItemArgumentsList.Add(readItemArguments2)
readItemArgumentsList.Add(readItemArguments3)
readItemArgumentsList.Add(readItemArguments4)

// Obtain values.
OLEObject valueResultList
valueResultList = client.ReadItemValueList(readItemArgumentsList)

// Display results
Int i
FOR i = 0 TO valueResultList.Count - 1
    OLEObject valueResult
    valueResult = valueResultList.Item[i]
    IF valueResult.Succeeded THEN
        mle_outputtext.Text = mle_outputtext.Text + "valueResult[" + String(i) + "].Value: " + String(valueResult.Value) + "~r~n"
    ELSE
        mle_outputtext.Text = mle_outputtext.Text + "valueResult[" + String(i) + "] *** Failure: " + valueResult.ErrorMessageBrief + "~r~n"
    END IF    
NEXT
Rem This example shows how to read values of 4 items at once, and display them.

Private Sub ReadMultipleItemValues_Main_Command_Click()
    OutputText = ""
    
    Dim readArguments1 As New DAReadItemArguments
    readArguments1.serverDescriptor.ServerClass = "OPCLabs.KitServer.2"
    readArguments1.ItemDescriptor.itemId = "Simulation.Random"
    
    Dim readArguments2 As New DAReadItemArguments
    readArguments2.serverDescriptor.ServerClass = "OPCLabs.KitServer.2"
    readArguments2.ItemDescriptor.itemId = "Trends.Ramp (1 min)"
    
    Dim readArguments3 As New DAReadItemArguments
    readArguments3.serverDescriptor.ServerClass = "OPCLabs.KitServer.2"
    readArguments3.ItemDescriptor.itemId = "Trends.Sine (1 min)"
    
    Dim readArguments4 As New DAReadItemArguments
    readArguments4.serverDescriptor.ServerClass = "OPCLabs.KitServer.2"
    readArguments4.ItemDescriptor.itemId = "Simulation.Register_I4"
    
    Dim arguments(3) As Variant
    Set arguments(0) = readArguments1
    Set arguments(1) = readArguments2
    Set arguments(2) = readArguments3
    Set arguments(3) = readArguments4

    ' Instantiate the client object
    Dim client As New EasyDAClient

    Dim results() As Variant
    results = client.ReadMultipleItemValues(arguments)

    ' Display results
    Dim i: For i = LBound(results) To UBound(results)
        Dim valueResult As valueResult: Set valueResult = results(i)
        If valueResult.Succeeded Then
            OutputText = OutputText & "results(" & i & ").Value: " & valueResult.value & vbCrLf
        Else
            OutputText = OutputText & "results(" & i & ") *** Failure: " & valueResult.ErrorMessageBrief & vbCrLf
        End If
    Next
End Sub
Rem This example shows how to read values of 4 items at once, and display them.

Option Explicit

Dim ReadItemArguments1: Set ReadItemArguments1 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
ReadItemArguments1.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
ReadItemArguments1.ItemDescriptor.ItemID = "Simulation.Random"

Dim ReadItemArguments2: Set ReadItemArguments2 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
ReadItemArguments2.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
ReadItemArguments2.ItemDescriptor.ItemID = "Trends.Ramp (1 min)"

Dim ReadItemArguments3: Set ReadItemArguments3 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
ReadItemArguments3.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
ReadItemArguments3.ItemDescriptor.ItemID = "Trends.Sine (1 min)"

Dim ReadItemArguments4: Set ReadItemArguments4 = CreateObject("OpcLabs.EasyOpc.DataAccess.OperationModel.DAReadItemArguments")
ReadItemArguments4.ServerDescriptor.ServerClass = "OPCLabs.KitServer.2"
ReadItemArguments4.ItemDescriptor.ItemID = "Simulation.Register_I4"

Dim arguments(3)
Set arguments(0) = ReadItemArguments1
Set arguments(1) = ReadItemArguments2
Set arguments(2) = ReadItemArguments3
Set arguments(3) = ReadItemArguments4

Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.DataAccess.EasyDAClient")
Dim results: results = Client.ReadMultipleItemValues(arguments)

Dim i: For i = LBound(results) To UBound(results)
    Dim ValueResult: Set ValueResult = results(i)
    If ValueResult.Succeeded Then
        WScript.Echo "results(" & i & ").Value: " & ValueResult.Value
    Else
        WScript.Echo "results(" & i & ") *** Failure: " & ValueResult.ErrorMessageBrief
    End If
Next

 

Example - OPC Unified Architecture

.NET

// This example shows how to read the Value attributes of 3 different nodes at once. Using the same method, it is also possible 
// to read multiple attributes of the same node.

using System;
using OpcLabs.BaseLib.OperationModel;
using OpcLabs.EasyOpc.UA;
using OpcLabs.EasyOpc.UA.OperationModel;

namespace UADocExamples._EasyUAClient
{
    partial class ReadMultipleValues
    {
        public static void Main1()
        {
            UAEndpointDescriptor endpointDescriptor =
                "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            // or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            // or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            // Instantiate the client object.
            var client = new EasyUAClient();

            // Obtain values. By default, the Value attributes of the nodes will be read.
            ValueResult[] valueResultArray = client.ReadMultipleValues(new[]
                {
                    new UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845"),
                    new UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853"),
                    new UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855")
                });

            // Display results.
            foreach (ValueResult valueResult in valueResultArray)
            {
                if (valueResult.Succeeded)
                    Console.WriteLine($"Value: {valueResult.Value}");
                else
                    Console.WriteLine($"*** Failure: {valueResult.ErrorMessageBrief}");
            }


            // Example output:
            //
            //Value: 8
            //Value: -8.06803E+21
            //Value: Strawberry Pig Banana Snake Mango Purple Grape Monkey Purple? Blueberry Lemon^            
        }
    }
}
# This example shows how to read the Value attributes of 3 different nodes at once. Using the same method, it is also possible 
# to read multiple attributes of the same node.

#requires -Version 5.1
using namespace OpcLabs.EasyOpc.UA
using namespace OpcLabs.EasyOpc.UA.OperationModel

# The path below assumes that the current directory is [ProductDir]/Examples-NET/PowerShell/Windows .
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUA.dll"
Add-Type -Path "../../../Components/Opclabs.QuickOpc/net472/OpcLabs.EasyOpcUAComponents.dll"

[UAEndpointDescriptor]$endpointDescriptor =
    "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
# or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
# or "https://opcua.demo-this.com:51212/UA/SampleServer/"

# Instantiate the client object.
$client = New-Object EasyUAClient

# Obtain values. By default, the Value attributes of the nodes will be read.
$valueResultArray = $client.ReadMultipleValues([UAReadArguments[]]@(
        (New-Object UAReadArguments($endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845")), 
        (New-Object UAReadArguments($endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853")), 
        (New-Object UAReadArguments($endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855"))
    ))

foreach ($valueResult in $valueResultArray) {
    if ($valueResult.Succeeded) {
        Write-Host "Value: $($valueResult.Value)"
    }
    else {
        Write-Host "*** Failure: $($valueResult.ErrorMessageBrief)"
    }
}


# Example output:
#
#Value: 8
#Value: -8.06803E+21
#Value: Strawberry Pig Banana Snake Mango Purple Grape Monkey Purple? Blueberry Lemon^            

# This example shows how to read the Value attributes of 3 different nodes at once. Using the same method, it is also possible
# to read multiple attributes of the same node.

# The QuickOPC package is needed. Install it using "pip install opclabs_quickopc".
import opclabs_quickopc
import time

# Import .NET namespaces.
from OpcLabs.EasyOpc.UA import *
from OpcLabs.EasyOpc.UA.OperationModel import *


endpointDescriptor = UAEndpointDescriptor('opc.tcp://opcua.demo-this.com:51210/UA/SampleServer')
# or 'http://opcua.demo-this.com:51211/UA/SampleServer' (currently not supported)
# or 'https://opcua.demo-this.com:51212/UA/SampleServer/'

# Instantiate the client object.
client = EasyUAClient()

# Obtain values. By default, the Value attributes of the nodes will be read.
valueResultArray = IEasyUAClientExtension.ReadMultipleValues(client, [
    UAReadArguments(endpointDescriptor, UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10845')),
    UAReadArguments(endpointDescriptor, UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10853')),
    UAReadArguments(endpointDescriptor, UANodeDescriptor('nsu=http://test.org/UA/Data/ ;i=10855')),
    ])

# Display results.
for valueResult in valueResultArray:
    if valueResult.Succeeded:
        print('Value: ', valueResult.Value, sep='')
    else:
        print('*** Failure: ', valueResult.ErrorMessageBrief, sep='')

print()
print('Finished.')
' This example shows how to read the Value attributes of 3 different nodes at once. Using the same method, it is also possible 
' to read multiple attributes of the same node.

Imports System
Imports OpcLabs.BaseLib.OperationModel
Imports OpcLabs.EasyOpc.UA
Imports OpcLabs.EasyOpc.UA.OperationModel

Namespace _EasyUAClient
    Partial Friend Class ReadMultipleValues
        Public Shared Sub Main1()

            ' Define which server we will work with.
            Dim endpointDescriptor As UAEndpointDescriptor =
                    "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
            ' or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
            ' or "https://opcua.demo-this.com:51212/UA/SampleServer/"

            ' Instantiate the client object
            Dim client = New EasyUAClient()

            ' Obtain values. By default, the Value attributes of the nodes will be read.
            Dim valueResultArray() As ValueResult = client.ReadMultipleValues(New UAReadArguments() _
               {
                   New UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10845"),
                   New UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10853"),
                   New UAReadArguments(endpointDescriptor, "nsu=http://test.org/UA/Data/ ;i=10855")
               }
            )

            ' Display results
            For Each valueResult As ValueResult In valueResultArray
                If valueResult.Succeeded Then
                    Console.WriteLine("Value: {0}", valueResult.Value)
                Else
                    Console.WriteLine("*** Failure: {0}", valueResult.ErrorMessageBrief)
                End If
            Next valueResult

            ' Example output:
            '
            'Value: 8
            'Value: -8.06803E+21
            'Value: Strawberry Pig Banana Snake Mango Purple Grape Monkey Purple? Blueberry Lemon^            
        End Sub
    End Class
End Namespace

COM

// This example shows how to read the Value attributes of 3 different nodes at once. Using the same method, it is also possible 
// to read multiple attributes of the same node.

#include "stdafx.h"    // Includes "QuickOpc.h", and other commonly used files
#include <atlsafe.h>
#include "ReadMultipleValues.h"

namespace _EasyUAClient
{
    void ReadMultipleValues::Main()
    {
        // Initialize the COM library
        CoInitializeEx(NULL, COINIT_MULTITHREADED);
        {
            // Instantiate the client object
            _EasyUAClientPtr ClientPtr(__uuidof(EasyUAClient));

            _UAReadArgumentsPtr ReadArguments1Ptr(_uuidof(UAReadArguments));
            ReadArguments1Ptr->EndpointDescriptor->UrlString = 
                //L"http://opcua.demo-this.com:51211/UA/SampleServer";
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            ReadArguments1Ptr->NodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10845";

            _UAReadArgumentsPtr ReadArguments2Ptr(_uuidof(UAReadArguments));
            ReadArguments2Ptr->EndpointDescriptor->UrlString = 
                //L"http://opcua.demo-this.com:51211/UA/SampleServer";
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            ReadArguments2Ptr->NodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10853";

            _UAReadArgumentsPtr ReadArguments3Ptr(_uuidof(UAReadArguments));
            ReadArguments3Ptr->EndpointDescriptor->UrlString = 
                //L"http://opcua.demo-this.com:51211/UA/SampleServer";
                L"opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
            ReadArguments3Ptr->NodeDescriptor->NodeId->ExpandedText = L"nsu=http://test.org/UA/Data/ ;i=10855";

            CComSafeArray<VARIANT> arguments(3);
            arguments.SetAt(0, _variant_t((IDispatch*)ReadArguments1Ptr));
            arguments.SetAt(1, _variant_t((IDispatch*)ReadArguments2Ptr));
            arguments.SetAt(2, _variant_t((IDispatch*)ReadArguments3Ptr));
            CComVariant vArguments(arguments);

            // Obtain values. By default, the Value attributes of the nodes will be read.
            CComSafeArray<VARIANT> results;
            results.Attach(ClientPtr->ReadMultipleValues(&vArguments));
            
            // Display results
            for (int i = results.GetLowerBound(); i <= results.GetUpperBound(); i++)
            {
                _ValueResultPtr ValueResultPtr = results[i];

                _variant_t vString;
                vString.ChangeType(VT_BSTR, &ValueResultPtr->Value);
                _tprintf(_T("Value: %s\n"), (LPCTSTR)CW2CT((_bstr_t)vString));
            }

            // Example output:
            //
            //Value: 8
            //Value: -8.06803E+21
            //Value: Strawberry Pig Banana Snake Mango Purple Grape Monkey Purple? Blueberry Lemon^            
        }
         // Release all interface pointers BEFORE calling CoUninitialize()
        CoUninitialize();
    }
}
// This example shows how to read the Value attributes of 3 different nodes at
// once. Using the same method, it is also possible to read multiple attributes
// of the same node.

class procedure ReadMultipleValues.Main;
var
  Client: EasyUAClient;
  ReadArguments1, ReadArguments2, ReadArguments3: _UAReadArguments;
  Arguments, Results: OleVariant;
  I: Cardinal;
  Result: _ValueResult;
begin
  // Instantiate the client object
  Client := CoEasyUAClient.Create;

  ReadArguments1 := CoUAReadArguments.Create;
  ReadArguments1.EndpointDescriptor.UrlString := 
    //'http://opcua.demo-this.com:51211/UA/SampleServer';
    'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer';
  ReadArguments1.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10845';

  ReadArguments2 := CoUAReadArguments.Create;
  ReadArguments2.EndpointDescriptor.UrlString := 
    //'http://opcua.demo-this.com:51211/UA/SampleServer';
    'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer';
  ReadArguments2.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10853';

  ReadArguments3 := CoUAReadArguments.Create;
  ReadArguments3.EndpointDescriptor.UrlString := 
    //'http://opcua.demo-this.com:51211/UA/SampleServer';
    'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer';
  ReadArguments3.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10855';

  Arguments := VarArrayCreate([0, 2], varVariant);
  Arguments[0] := ReadArguments1;
  Arguments[1] := ReadArguments2;
  Arguments[2] := ReadArguments3;

  // Obtain values. By default, the Value attributes of the nodes will be read.
  TVarData(Results).VType := varArray or varVariant;
  TVarData(Results).VArray := PVarArray(Client.ReadMultipleValues(
    PSafeArray(TVarData(Arguments).VArray)));

  // Display results
  for I := VarArrayLowBound(Results, 1) to VarArrayHighBound(Results, 1) do
  begin
      Result := IInterface(Results[I]) as _ValueResult;
      WriteLn('Value: ', Result.Value);
  end;

  // Example output:
  //
  //Value: 8
  //Value: -8.06803E+21
  //Value: Strawberry Pig Banana Snake Mango Purple Grape Monkey Purple? Blueberry Lemon^
end;
// This example shows how to read the Value attributes of 3 different nodes at
// once. Using the same method, it is also possible to read multiple attributes
// of the same node.

class procedure ReadMultipleValues.Main;
var
  Client: OpcLabs_EasyOpcUA_TLB._EasyUAClient;
  ReadArguments1, ReadArguments2, ReadArguments3: _UAReadArguments;
  Arguments, Results: OleVariant;
  I: Cardinal;
  Result: _ValueResult;
begin
  // Instantiate the client object
  Client := CoEasyUAClient.Create;

  ReadArguments1 := CoUAReadArguments.Create;
  ReadArguments1.EndpointDescriptor.UrlString := 
    //'http://opcua.demo-this.com:51211/UA/SampleServer';
    //'https://opcua.demo-this.com:51212/UA/SampleServer/';
    'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer';
  ReadArguments1.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10845';

  ReadArguments2 := CoUAReadArguments.Create;
  ReadArguments2.EndpointDescriptor.UrlString := 
    //'http://opcua.demo-this.com:51211/UA/SampleServer';
    //'https://opcua.demo-this.com:51212/UA/SampleServer/';
    'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer';
  ReadArguments2.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10853';

  ReadArguments3 := CoUAReadArguments.Create;
  ReadArguments3.EndpointDescriptor.UrlString := 
    //'http://opcua.demo-this.com:51211/UA/SampleServer';
    //'https://opcua.demo-this.com:51212/UA/SampleServer/';
    'opc.tcp://opcua.demo-this.com:51210/UA/SampleServer';
  ReadArguments3.NodeDescriptor.NodeId.ExpandedText := 'nsu=http://test.org/UA/Data/ ;i=10855';

  Arguments := VarArrayCreate([0, 2], varVariant);
  Arguments[0] := ReadArguments1;
  Arguments[1] := ReadArguments2;
  Arguments[2] := ReadArguments3;

  // Obtain values. By default, the Value attributes of the nodes will be read.
  TVarData(Results).VType := varArray or varVariant;
  TVarData(Results).VArray := PVarArray(Client.ReadMultipleValues(Arguments));

  // Display results
  for I := VarArrayLowBound(Results, 1) to VarArrayHighBound(Results, 1) do
  begin
      Result := IInterface(Results[I]) as _ValueResult;
      if Result.Succeeded then
        WriteLn('Value: ', Result.Value)
      else
        WriteLn('results(', I, ') *** Failure: ', Result.ErrorMessageBrief);
  end;

  VarClear(Results);
  VarClear(Arguments);

  // Example output:
  //
  //Value: 8
  //Value: -8.06803E+21
  //Value: Strawberry Pig Banana Snake Mango Purple Grape Monkey Purple? Blueberry Lemon^
end;
// This example shows how to read the Value attributes of 3 different nodes at once. Using the same method, it is also possible 
// to read multiple attributes of the same node.

// Instantiate the client object
$Client = new COM("OpcLabs.EasyOpc.UA.EasyUAClient");

$ReadArguments1 = new COM("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments");
$ReadArguments1->EndpointDescriptor->UrlString = 
    //"http://opcua.demo-this.com:51211/UA/SampleServer";
    //"https://opcua.demo-this.com:51212/UA/SampleServer/";
    "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
$ReadArguments1->NodeDescriptor->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10845";

$ReadArguments2 = new COM("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments");
$ReadArguments2->EndpointDescriptor->UrlString = "
    //"http://opcua.demo-this.com:51211/UA/SampleServer";
    //"https://opcua.demo-this.com:51212/UA/SampleServer/";
    "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
$ReadArguments2->NodeDescriptor->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853";

$ReadArguments3 = new COM("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments");
$ReadArguments3->EndpointDescriptor->UrlString = 
    //"http://opcua.demo-this.com:51211/UA/SampleServer";
    //"https://opcua.demo-this.com:51212/UA/SampleServer/";
    "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
$ReadArguments3->NodeDescriptor->NodeId->ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10855";

$arguments[0] = $ReadArguments1;
$arguments[1] = $ReadArguments2;
$arguments[2] = $ReadArguments3;

// Obtain values. By default, the Value attributes of the nodes will be read.
$results = $Client->ReadMultipleValues($arguments);

// Display results
for ($i = 0; $i < count($results); $i++)
{
    $ValueResult = $results[$i];
    if ($ValueResult->Succeeded)
        printf("Value: %s\n", $ValueResult->Value);
    else
        printf("*** Failure: %s\n", $ValueResult->ErrorMessageBrief);
}

// Example output:
//
//Value: 8
//Value: -8.06803E+21
//Value: Strawberry Pig Banana Snake Mango Purple Grape Monkey Purple? Blueberry Lemon^            

// This example shows how to read the Value attributes of 3 different nodes at once. Using the same method, it is also possible 
// to read multiple attributes of the same node.

mle_outputtext.Text = ""

// Instantiate the client object
OLEObject client
client = CREATE OLEObject
client.ConnectToNewObject("OpcLabs.EasyOpc.UA.EasyUAClient")

// Prepare arguments. By default, the Value attributes of the nodes will be read.

OLEObject readArguments1
readArguments1 = CREATE OLEObject
readArguments1.ConnectToNewObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
readArguments1.EndpointDescriptor.UrlString = "http://opcua.demo-this.com:51211/UA/SampleServer"
readArguments1.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10845"

OLEObject readArguments2
readArguments2 = CREATE OLEObject
readArguments2.ConnectToNewObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
readArguments2.EndpointDescriptor.UrlString = "http://opcua.demo-this.com:51211/UA/SampleServer"
readArguments2.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853"

OLEObject readArguments3
readArguments3 = CREATE OLEObject
readArguments3.ConnectToNewObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
readArguments3.EndpointDescriptor.UrlString = "http://opcua.demo-this.com:51211/UA/SampleServer"
readArguments3.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10855"

OLEObject readArgumentsList
readArgumentsList = CREATE OLEObject
readArgumentsList.ConnectToNewObject("OpcLabs.BaseLib.Collections.ElasticVector")
readArgumentsList.Add(readArguments1)
readArgumentsList.Add(readArguments2)
readArgumentsList.Add(readArguments3)

// Obtain values. 
OLEObject valueResultList
valueResultList = client.ReadValueList(readArgumentsList)

// Display results
Int i
FOR i = 0 TO valueResultList.Count - 1
    OLEObject valueResult
    valueResult = valueResultList.Item[i]
    IF valueResult.Succeeded THEN
        mle_outputtext.Text = mle_outputtext.Text + "Value: " + String(valueResult.Value) + "~r~n"
    ELSE
        mle_outputtext.Text = mle_outputtext.Text + "*** Failure: " + valueResult.ErrorMessageBrief + "~r~n"
    END IF    
NEXT

// Example output:
//
//Value: 8
//Value: -8.06803E+21
//Value: Strawberry Pig Banana Snake Mango Purple Grape Monkey Purple? Blueberry Lemon^            

Rem This example shows how to read the Value attributes of 3 different nodes at once. Using the same method, it is also possible
Rem to read multiple attributes of the same node.

Public Sub ReadMultipleValues_Main_Command_Click()
    OutputText = ""

    ' Instantiate the client object
    Dim Client As New EasyUAClient

    Dim readArguments1 As New UAReadArguments
    readArguments1.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    readArguments1.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10845"

    Dim ReadArguments2 As New UAReadArguments
    ReadArguments2.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    ReadArguments2.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10853"

    Dim ReadArguments3 As New UAReadArguments
    ReadArguments3.endpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    ReadArguments3.nodeDescriptor.NodeId.expandedText = "nsu=http://test.org/UA/Data/ ;i=10855"

    Dim arguments(2) As Variant
    Set arguments(0) = readArguments1
    Set arguments(1) = ReadArguments2
    Set arguments(2) = ReadArguments3

    ' Obtain values. By default, the Value attributes of the nodes will be read.
    Dim results() As Variant
    results = Client.ReadMultipleValues(arguments)

    ' Display results
    Dim i: For i = LBound(results) To UBound(results)
        Dim Result As valueResult: Set Result = results(i)
        If Result.Succeeded Then
            OutputText = OutputText & "Value: " & Result.value & vbCrLf
        Else
            OutputText = OutputText & "*** Failure: " & Result.ErrorMessageBrief & vbCrLf
        End If
    Next

    ' Example output:
    '
    'Value: 8
    'Value: -8.06803E+21
    'Value: Strawberry Pig Banana Snake Mango Purple Grape Monkey Purple? Blueberry Lemon^
End Sub
Rem This example shows how to read the Value attributes of 3 different nodes at once. Using the same method, it is also possible 
Rem to read multiple attributes of the same node.

Option Explicit

' Instantiate the client object
Dim Client: Set Client = CreateObject("OpcLabs.EasyOpc.UA.EasyUAClient")

Dim ReadArguments1: Set ReadArguments1 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
ReadArguments1.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
ReadArguments1.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10845"

Dim ReadArguments2: Set ReadArguments2 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
ReadArguments2.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
ReadArguments2.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10853"

Dim ReadArguments3: Set ReadArguments3 = CreateObject("OpcLabs.EasyOpc.UA.OperationModel.UAReadArguments")
ReadArguments3.EndpointDescriptor.UrlString = "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
ReadArguments3.NodeDescriptor.NodeId.ExpandedText = "nsu=http://test.org/UA/Data/ ;i=10855"

Dim arguments(2)
Set arguments(0) = ReadArguments1
Set arguments(1) = ReadArguments2
Set arguments(2) = ReadArguments3

' Obtain values. By default, the Value attributes of the nodes will be read.
Dim results: results = Client.ReadMultipleValues(arguments)

' Display results
Dim i: For i = LBound(results) To UBound(results)
    Dim ValueResult: Set ValueResult = results(i)
    If ValueResult.Succeeded Then
        WScript.Echo "Value: " & ValueResult.Value
    Else
        WScript.Echo "*** Failure: " & ValueResult.ErrorMessageBrief
    End If
Next

' Example output:
'
'Value: 8
'Value: -8.06803E+21
'Value: Strawberry Pig Banana Snake Mango Purple Grape Monkey Purple? Blueberry Lemon^            

 

See Also

Examples - OPC Data Access

Examples - OPC Unified Architecture